package controller

import (
	"github.com/gin-contrib/sessions"
	"struggle/dao/mysql"
	"struggle/model"
	"struggle/pkg/myJWT"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// SignUpHandler godoc
// @Summary 注册用户
// @Description 添加一个新用户到数据库
// @Tags user
// @Accept  json
// @Produce  json
// @Param email password confirm_password
// @Success 200 {object} user.CreateResponse "{ "code": 1000, "message": "success", "data": null }"
// @Router /api/signup [post]
func SignUpHandler(c *gin.Context) {
	// 1. 提取用户提交的注册信息
	// 2. 并进行数据校验
	var sd model.SignUpForm
	if err := c.ShouldBindJSON(&sd); err != nil {
		// 返回参数错误的响应
		zap.L().Error("invalid params", zap.Error(err))
		ResponseErrorWithMsg(c, CodeInvalidParams, err.Error())
		return
	}
	// 3. 保存到数据库
	u := &model.User{
		Email:    sd.Email,
		Password: sd.Password,
	}
	if err := mysql.Register(u); err != nil {
		ResponseErrorWithMsg(c, CodeServerBusy, err.Error())
		return
	}
	// 4. 返回响应
	ResponseSuccess(c, nil)
}

func LoginHandler(c *gin.Context) {
	// 1. 获取请求数据，登录需要的额邮箱、密码
	var u model.User
	if err := c.ShouldBindJSON(&u); err != nil {
		ResponseErrorWithMsg(c, CodeInvalidParams, err.Error())
		return
	}
	// 2. 去数据库校验用户邮箱和密码是否正确
	if err := mysql.Login(&u); err != nil {
		ResponseError(c, CodeInvalidPassword)
		return
	}
	// 3. 生成 JWT Token
	tokenString, err := myJWT.GenToken(u.UserSn)
	if err != nil {
		zap.L().Error("myJWT.GenToken failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
		return
	}
	session := sessions.Default(c)
	session.Set("token", tokenString)
	session.Save()
	// 如果基于 Cookie/Session 的模式
	// 生成 Cookie 值，并生成后端的 session 数据
	// Cookie 值返回给客户端中到浏览器的 Cookie 中
	// 4. 返回响应
	ResponseSuccess(c, gin.H{
		"token":  tokenString,
		"userSn": u.UserSn,
		"email":  u.Email,
	})
}

type MemberController struct{}

var DefaultMemberController = &MemberController{}

func (u MemberController) CheckAuthHandler(c *gin.Context) {
	userSn, err := getCurrentUserSn(c)
	if err != nil {
		zap.L().Error("用户上传操作时未登录")
		ResponseError(c, CodeNotLogin)
		return
	}
	// 构造返回数据
	ResponseSuccess(c, map[string]interface{}{"userSn": userSn})
}
